package com.fjwt.gz.mgr.ctrl.anon;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.codec.Base64;
import cn.hutool.core.lang.UUID;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fjwt.gz.core.aop.MethodLog;
import com.fjwt.gz.core.cache.RedisUtil;
import com.fjwt.gz.core.constants.ApiCodeEnum;
import com.fjwt.gz.core.constants.CS;
import com.fjwt.gz.core.exception.BizException;
import com.fjwt.gz.core.model.ApiRes;
import com.fjwt.gz.db.entity.SysUser;
import com.fjwt.gz.db.entity.SysUserAuth;
import com.fjwt.gz.mgr.ctrl.CommonCtrl;
import com.fjwt.gz.mgr.service.AuthService;
import com.fjwt.gz.service.impl.SysUserAuthService;
import com.fjwt.gz.service.impl.SysUserService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

/*
* 认证接口
*
* @author wg
* @site https://pt.jdyd.xyz/
* @date 2021/6/8 17:09
*/
@RestController
@RequestMapping("/api/anon/auth")
@Slf4j
public class AuthController extends CommonCtrl {

	@Autowired private AuthService authService;
	@Autowired
	private SysUserService sysUserService;

	@Autowired
	private SysUserAuthService sysUserAuthService;

	/**
	 * getValString("ia");
	 * getValString("ip");
	 * getValString("vc");
	 *
	 * @return
	 */
	@MethodLog(remark = "登录")
	@PostMapping("/login")
	public ApiRes login(){
		SysUser user = null;
		String account =    Base64.decodeStr(getValStringRequired("ia"));  //用户名 i account, 已做base64处理
		String ipassport =  Base64.decodeStr(getValStringRequired("ip"));	//密码 i passport,  已做base64处理
		String vercode =    Base64.decodeStr(getValStringRequired("vc"));// 手机验证码
		log.info("pc端登录，请求地址：/api/anon/auth/login，请求参数：account：{}，ip：{}，vercode：{}",account,ipassport,vercode);
		// 根据手机号查询
		LambdaQueryWrapper<SysUser> queryWrapperPhone = new LambdaQueryWrapper<>();
		queryWrapperPhone.eq(SysUser::getTelphone,account);
		queryWrapperPhone.eq(SysUser::getSysType,CS.SYS_ROLE_TYPE.MANAGER);
		user = sysUserService.getOne(queryWrapperPhone);
		if(null == user){
			return ApiRes.customFail("登录用户不存在！");
		}

		if(StringUtils.isEmpty(vercode)){
			return ApiRes.customFail("请输入验证码！");
		}
		// 验证码校验
		String codeJsonStr = RedisUtil.getString(CS.getLoginCacheKeySmsCode(CS.SYS_ROLE_TYPE.MANAGER, user.getTelphone()));
		if (StringUtils.isEmpty(codeJsonStr)) {
			throw new BizException("验证码已过期，请重新点击发送验证码！");
		}
		JSONObject codeJson = JSONObject.parseObject(codeJsonStr);
		String cacheCode = codeJson.getString("code");
		if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
			throw new BizException("验证码错误！");
		}
		LambdaQueryWrapper<SysUserAuth> userAuthQuery = new LambdaQueryWrapper<>();
		userAuthQuery.eq(SysUserAuth::getUserId,user.getSysUserId());
		SysUserAuth userAuth = sysUserAuthService.getOne(userAuthQuery);
		if(null != userAuth.getIsUpdatePwd()){
			if(1==userAuth.getIsUpdatePwd()){
				return ApiRes.fail(ApiCodeEnum.SYS_NEED_UPDATE_PWD);
			}
		}

		return authService.authByAuthentication(user.getTelphone(), ipassport,"","");
	}

	/**
	 * 强制修改密码
	 * @return
	 */
	@PostMapping("/updatePwd")
	public ApiRes updatePwd(){
		String telphone = Base64.decodeStr(getValStringRequired("telphone"));
		String newPwd =  Base64.decodeStr(getValStringRequired("newPwd"));
//		String vercode = Base64.decodeStr(getValStringRequired("vc"));
		String confirmPwd = Base64.decodeStr(getValStringRequired("confirmPwd"));
		log.info("pc端修改密码，请求地址：/api/anon/auth/updatePwd，请求参数：telphone：{}，newPwd：{}，confirmPwd：{}",telphone,newPwd,confirmPwd);
		if(!newPwd.equals(confirmPwd)){
			return ApiRes.customFail("两次输入密码不一致！");
		}
//		String codeJsonStr = RedisUtil.getString(CS.getUpdatepwdCacheKeySmsCode(CS.SYS_ROLE_TYPE.PLATFORM, telphone));
//		if (StringUtils.isEmpty(codeJsonStr)) {
//			throw new BizException("验证码已过期，请重新点击发送验证码！");
//		}
//		JSONObject codeJson = JSONObject.parseObject(codeJsonStr);
//		String cacheCode = codeJson.getString("code");
//		if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
//			throw new BizException("验证码错误！");
//		}
		LambdaQueryWrapper<SysUser> queryWrapperPhone = new LambdaQueryWrapper<>();
		queryWrapperPhone.eq(SysUser::getTelphone,telphone);
		queryWrapperPhone.eq(SysUser::getSysType,CS.SYS_ROLE_TYPE.MANAGER);
		SysUser user = sysUserService.getOne(queryWrapperPhone);
		if(null == user){
			return ApiRes.customFail("用户不存在或密码错误！");
		}
		sysUserAuthService.resetAuthInfo(user.getSysUserId(), null, null, true, newPwd, CS.SYS_ROLE_TYPE.MANAGER);
		return ApiRes.ok();
	}

	/** 用户信息认证 获取iToken  **/
	@RequestMapping(value = "/validate", method = RequestMethod.POST)
	@MethodLog(remark = "登录认证")
	public ApiRes validate() throws BizException {


		String account = Base64.decodeStr(getValStringRequired("ia"));  //用户名 i account, 已做base64处理
		String ipassport = Base64.decodeStr(getValStringRequired("ip"));	//密码 i passport,  已做base64处理
        String vercode = Base64.decodeStr(getValStringRequired("vc"));	//验证码 vercode,  已做base64处理
        String vercodeToken = Base64.decodeStr(getValStringRequired("vt"));	//验证码token, vercode token ,  已做base64处理

		String mfaCode = StringUtils.isEmpty(getValString("mc")) ? null : Base64.decodeStr(getValString("mc"));	// MFACode,  已做base64处理
		log.info("pc端用户信息认证获取iToken，请求地址：/api/anon/auth/validate，请求参数：account：{}，ip：{}，vercode：{}，vercodeToken：{}，mfaCode：{}",account,ipassport,vercode,vercodeToken,mfaCode);
		// 验证码校验: WEB登录 & 第一次认证（MFACode为空的情况）
		if(StringUtils.isEmpty(mfaCode)){
			String cacheCode = RedisUtil.getString(CS.getCacheKeyImgCode(vercodeToken));
			if(StringUtils.isEmpty(cacheCode) || !cacheCode.equalsIgnoreCase(vercode)){
				throw new BizException("验证码有误！");
			}
		}

		// 返回前端 accessToken
		return authService.authByAuthentication(account, ipassport, vercodeToken, mfaCode);
	}


	/** 图片验证码  **/
	@RequestMapping(value = "/vercode", method = RequestMethod.GET)
	public ApiRes vercode() throws BizException {

		//定义图形验证码的长和宽 // 4位验证码
		LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(137, 40, 4, 80);
        lineCaptcha.createCode(); //生成code

        //redis
		String vercodeToken = UUID.fastUUID().toString();
        RedisUtil.setString(CS.getCacheKeyImgCode(vercodeToken), lineCaptcha.getCode(), CS.VERCODE_CACHE_TIME ); //图片验证码缓存时间: 1分钟

        JSONObject result = new JSONObject();
        result.put("imageBase64Data", lineCaptcha.getImageBase64Data());
        result.put("vercodeToken", vercodeToken);
		result.put("expireTime", CS.VERCODE_CACHE_TIME);
		log.info("pc端获取图片验证码，请求地址：/api/anon/auth/vercode，返回参数：{}", JSONUtil.toJsonStr(result));
		return ApiRes.ok(result);
	}

}
